function UnitHasItemOfCategoryExcept takes unit who , integer itemCategory , item exception returns boolean
	local integer whichSlot = 0
	local item whichItem = null
	local boolean has = false
	//--
	loop
	exitwhen whichSlot >= 6
		set whichItem = UnitItemInSlot(who , whichSlot)
		if whichItem != null and whichItem != exception and LoadInteger(udg_ItemTypeDataHashTable , GetItemTypeId(whichItem) , StringHash("ITEM_CATEGORY")) == itemCategory then
			set has = true
			exitwhen true
		endif
	set whichSlot = whichSlot + 1
	endloop	
	//--
	set whichItem = null
	return has
endfunction

function PlayerGetWeaponAbilities takes player owner , integer itemTypeId returns nothing
	local hashtable ownerAvailableAbilityTable = LoadHashtableHandle(udg_PlayerDataHashTable , GetHandleId(owner) , StringHash("ABILITY_AVAILABLE_TABLE"))
	local hashtable ownerPreferAbilityTable = LoadHashtableHandle(udg_PlayerDataHashTable , GetHandleId(owner) , StringHash("PREFER_ABILITY_TABLE"))
	local integer weaponType = LoadInteger(udg_ItemTypeDataHashTable , itemTypeId , StringHash("WEAPON_TYPE"))
	local hashtable weaponTypeAbilityTable = LoadHashtableHandle(udg_WeaponTypeDataHashTable , weaponType , StringHash("ABILITIES"))
	local integer amountOfAbilities = LoadInteger(weaponTypeAbilityTable , -1 , StringHash("SIZE"))
	local integer whichAbilityIndex = 0
	local integer abilityId = 0
	local integer hotKey = 0
	//--
	loop
		exitwhen whichAbilityIndex >= amountOfAbilities
		set abilityId = LoadInteger(weaponTypeAbilityTable , whichAbilityIndex , StringHash("ABILITY"))
		set hotKey = LoadInteger(weaponTypeAbilityTable , whichAbilityIndex , StringHash("HOTKEY"))
		if LoadBoolean(ownerAvailableAbilityTable , abilityId , StringHash("LEARNED")) then
			if LoadInteger(ownerPreferAbilityTable , weaponType , hotKey) == abilityId then
				call SetPlayerAbilityAvailable(owner , abilityId , true)
				call SetPlayerAbilityAvailable(owner , GetDefaultAbility(hotKey) , false)
			endif
		endif
		set whichAbilityIndex = whichAbilityIndex + 1	
	endloop
	//--
	set ownerAvailableAbilityTable = null
	set ownerPreferAbilityTable = null
	set weaponTypeAbilityTable = null
endfunction

function PlayerRemoveWeaponAbilities takes unit unitToRemoveAbilities , integer itemTypeId returns nothing
	local player owner = GetOwningPlayer(unitToRemoveAbilities)
	local integer weaponType = LoadInteger(udg_ItemTypeDataHashTable , itemTypeId , StringHash("WEAPON_TYPE"))
	local hashtable weaponTypeAbilityTable = LoadHashtableHandle(udg_WeaponTypeDataHashTable , weaponType , StringHash("ABILITIES"))
	local integer amountOfAbilities = LoadInteger(weaponTypeAbilityTable , -1 , StringHash("SIZE"))
	local integer whichAbilityIndex = 0
	local integer abilityId = 0
	local integer hotKey = 0
	//--
	loop
		exitwhen whichAbilityIndex >= amountOfAbilities
		set abilityId = LoadInteger(weaponTypeAbilityTable , whichAbilityIndex , StringHash("ABILITY"))
		set hotKey = LoadInteger(weaponTypeAbilityTable , whichAbilityIndex , StringHash("HOTKEY"))
		call SetPlayerAbilityAvailable(owner , abilityId , false)
		if not UnitHasItemOfCategoryExcept(unitToRemoveAbilities , StringHash("MAIN_WEAPON") , null) then
			call SetPlayerAbilityAvailable(owner , GetDefaultAbility(hotKey) , true)
		endif
		set whichAbilityIndex = whichAbilityIndex + 1	
	endloop
	//--
	set weaponTypeAbilityTable = null
endfunction

function SwitchAbilityByInstruction takes nothing returns nothing
	local string hotkeyString = SubString(GetEventPlayerChatString() , 2 , 3)
	local integer hotkey = LoadInteger(udg_InstructionHashTable , StringHash(hotkeyString) , StringHash("REAL_HOTKEY"))
	local integer defaultAbility = GetDefaultAbility(hotkey)
	local integer weaponType = LoadInteger(udg_TriggerDataHashTable , GetHandleId(GetTriggeringTrigger()) , StringHash("WEAPON_TYPE"))
	local integer weaponAbility = LoadInteger(udg_WeaponTypeDataHashTable , weaponType , hotkey)
	local player triggerPlayer = GetTriggerPlayer()
	local hashtable ownerPreferAbilityTable = LoadHashtableHandle(udg_PlayerDataHashTable , GetHandleId(triggerPlayer) , StringHash("PREFER_ABILITY_TABLE"))
	local hashtable ownerAvailableAbilityTable = LoadHashtableHandle(udg_PlayerDataHashTable , GetHandleId(triggerPlayer) , StringHash("ABILITY_AVAILABLE_TABLE"))
	//--
	if LoadBoolean(ownerAvailableAbilityTable , weaponAbility , StringHash("LEARNED")) then
		if LoadInteger(ownerPreferAbilityTable , weaponType , hotkey) == weaponAbility then
			call SaveInteger(ownerPreferAbilityTable , weaponType , hotkey , defaultAbility)
			call SetPlayerAbilityAvailable(triggerPlayer , defaultAbility , true)
			call SetPlayerAbilityAvailable(triggerPlayer , weaponAbility , false)
		else
			call SaveInteger(ownerPreferAbilityTable , weaponType , hotkey , weaponAbility)
				call SetPlayerAbilityAvailable(triggerPlayer , defaultAbility , false)
				call SetPlayerAbilityAvailable(triggerPlayer , weaponAbility , true)
		endif
	endif
	//--
	set hotkeyString = null
	set triggerPlayer = null
	set ownerPreferAbilityTable = null
	set ownerAvailableAbilityTable = null
endfunction

function DestroyInstructionTrigger takes player pickerOwner returns nothing
	local trigger switchTrigger = LoadTriggerHandle(udg_PlayerDataHashTable , GetHandleId(pickerOwner) , StringHash("SWITCH_ABILITY_TRIGGER"))
	local triggeraction action = LoadTriggerActionHandle(udg_TriggerDataHashTable , GetHandleId(switchTrigger) , StringHash("TRIGGER_ACTION"))
	//--
	call RemoveSavedHandle(udg_PlayerDataHashTable , GetHandleId(pickerOwner) , StringHash("SWITCH_ABILITY_TRIGGER"))
	call FlushChildHashtable(udg_TriggerDataHashTable , GetHandleId(switchTrigger))
	call TriggerRemoveAction(switchTrigger , action)
	call DestroyTrigger(switchTrigger)
	//--
	set switchTrigger = null
	set action = null
endfunction

function CreateInstructionTrigger takes player pickerOwner , item pickingItem returns nothing
	local trigger switchTrigger = CreateTrigger()
	local triggeraction action = null
	local integer weaponType = LoadInteger(udg_ItemTypeDataHashTable , GetItemTypeId(pickingItem) , StringHash("WEAPON_TYPE"))
	//--
	call TriggerRegisterPlayerChatEvent(switchTrigger , pickerOwner , "-sq" , true)
	call TriggerRegisterPlayerChatEvent(switchTrigger , pickerOwner , "-sw" , true)
	call SaveInteger(udg_TriggerDataHashTable , GetHandleId(switchTrigger) , StringHash("WEAPON_TYPE") , weaponType)
	set action = TriggerAddAction(switchTrigger , function SwitchAbilityByInstruction)
	call SaveTriggerHandle(udg_PlayerDataHashTable , GetHandleId(pickerOwner) , StringHash("SWITCH_ABILITY_TRIGGER") , switchTrigger)
	call SaveTriggerActionHandle(udg_TriggerDataHashTable , GetHandleId(switchTrigger) , StringHash("TRIGGER_ACTION") , action)
	//--
	set switchTrigger = null
	set action = null
endfunction

function RemoveItemPassiveAbilities takes unit picker , item droppingItem returns nothing
	local integer weaponType = LoadInteger(udg_ItemTypeDataHashTable , GetItemTypeId(droppingItem) , StringHash("WEAPON_TYPE"))
	local real blockProbability = LoadReal(udg_ItemDataHashTable , GetHandleId(droppingItem) , StringHash("BLOCK_PROBABILITY"))
	//--
	//盾牌格擋
	if weaponType == StringHash("SHIELD") then
		call SaveReal(udg_UnitDataHashTable , GetHandleId(picker) , StringHash("BLOCK_DAMAGE_PROBABILITY") , LoadReal(udg_UnitDataHashTable , GetHandleId(picker) , StringHash("BLOCK_DAMAGE_PROBABILITY")) - blockProbability)
	endif
endfunction

function GetItemPassiveAbilities takes unit picker , item pickingItem returns nothing
	local integer weaponType = LoadInteger(udg_ItemTypeDataHashTable , GetItemTypeId(pickingItem) , StringHash("WEAPON_TYPE"))
	local real blockProbability = LoadReal(udg_ItemDataHashTable , GetHandleId(pickingItem) , StringHash("BLOCK_PROBABILITY"))
	//--
	//盾牌格擋
	if weaponType == StringHash("SHIELD") then
		call SaveReal(udg_UnitDataHashTable , GetHandleId(picker) , StringHash("BLOCK_DAMAGE_PROBABILITY") , LoadReal(udg_UnitDataHashTable , GetHandleId(picker) , StringHash("BLOCK_DAMAGE_PROBABILITY")) + blockProbability)
	endif
endfunction

function Trig_PickUpItem_Actions takes nothing returns nothing
	local unit picker = GetTriggerUnit()
	local item pickingItem = GetManipulatedItem()
	local integer itemTypeId = GetItemTypeId(pickingItem)
	local integer itemCategory = 0
	//--
	if GetUnitTypeId(picker) == 'h000' and HaveSavedInteger(udg_ItemTypeDataHashTable , itemTypeId , StringHash("ITEM_CATEGORY")) then
		set itemCategory = LoadInteger(udg_ItemTypeDataHashTable , itemTypeId , StringHash("ITEM_CATEGORY"))
		if itemCategory == StringHash("MAIN_WEAPON") and UnitHasItemOfCategoryExcept(picker , StringHash("MAIN_WEAPON") , pickingItem) then
			call SetItemPosition(pickingItem , GetItemX(pickingItem) , GetItemY(pickingItem))
			call DisplayTimedTextToPlayer(GetOwningPlayer(picker) , 0 , 0 , 2.0 , "你一次只能使用一種主要武器") 
		else
			call PlayerGetWeaponAbilities(GetOwningPlayer(picker) , itemTypeId)	
			call CreateInstructionTrigger(GetOwningPlayer(picker) , pickingItem)
			call GetItemPassiveAbilities(picker , pickingItem)
		endif
	endif
	//--
	set picker = null
	set pickingItem = null
endfunction

function DropItemAction takes nothing returns nothing
	local timer checkTimer = GetExpiredTimer()
	local integer timerId = GetHandleId(checkTimer)
	local unit who = LoadUnitHandle(udg_HT , timerId , StringHash("DROPER"))
	local item droppingItem = LoadItemHandle(udg_HT , timerId , StringHash("DROPPING_ITEM"))
	local player owner = GetOwningPlayer(who)
	//--
	if not UnitHasItem(who , droppingItem) then
		call PlayerRemoveWeaponAbilities(who , GetItemTypeId(droppingItem))
		call DestroyInstructionTrigger(owner)
		call RemoveItemPassiveAbilities(who , droppingItem)
	endif
	
	call PauseTimer(checkTimer)
	call FlushChildHashtable(udg_HT , timerId)
	call DestroyTimer(checkTimer)
	//--
	set checkTimer = null
	set who = null
	set droppingItem = null
	set owner = null
endfunction

function DropItemStart takes nothing returns nothing
	local unit who = GetTriggerUnit()	
	local timer checkTimer = null
	local integer timerId = 0
	//--
	if GetUnitTypeId(who) == 'h000' then
		set checkTimer = CreateTimer()
		set timerId = GetHandleId(checkTimer)
		call SaveUnitHandle(udg_HT , timerId , StringHash("DROPER") , who)
		call SaveItemHandle(udg_HT , timerId , StringHash("DROPPING_ITEM") , GetManipulatedItem())
		call TimerStart(checkTimer , 0.0 , false , function DropItemAction)
	endif
	//--
	set who = null
	set checkTimer = null
endfunction

function InitTrig_ItemSystem takes nothing returns nothing
	local trigger pickUpItem = CreateTrigger()
	local trigger dropItem = CreateTrigger()
	//--
	//pick up
	call TriggerRegisterPlayerForceUnitEvent(pickUpItem , EVENT_PLAYER_UNIT_PICKUP_ITEM)
	call TriggerAddAction(pickUpItem , function Trig_PickUpItem_Actions)
	//drop down
	call TriggerRegisterPlayerForceUnitEvent(dropItem , EVENT_PLAYER_UNIT_DROP_ITEM)
	call TriggerAddAction(dropItem , function DropItemStart)
	//--
	set pickUpItem = null
	set dropItem = null
endfunction